package com.fastCms.business.frame.busi.impl;

import com.fastCms.business.frame.busi.CloudMenuManageService;
import com.fastCms.business.frame.constant.CommonConst;
import com.fastCms.business.frame.constant.ResultCodeConst;
import com.fastCms.business.frame.daos.CloudMenuMapper;
import com.fastCms.business.frame.enums.CloudAdminTypeEnum;
import com.fastCms.business.frame.manage.CloudUserManage;
import com.fastCms.business.frame.pojo.entity.CloudMenu;
import com.fastCms.business.frame.pojo.entity.CloudRoleMenu;
import com.fastCms.business.frame.pojo.entity.CloudUser;
import com.fastCms.business.frame.pojo.entity.CloudUserRoleRel;
import com.fastCms.business.frame.pojo.po.MenuOfUserPO;
import com.fastCms.business.frame.pojo.po.MenuPointOfUserPO;
import com.fastCms.business.frame.pojo.vo.CloudMenuVO;
import com.fastCms.business.frame.response.ApiResponse;
import com.fastCms.business.frame.response.ResponseUtil;
import com.fastCms.business.frame.service.CloudMenuService;
import com.fastCms.business.frame.service.CloudRoleMenuService;
import com.fastCms.business.frame.service.CloudUserRoleRelService;
import com.fastCms.business.frame.service.CloudUserService;
import com.fastCms.business.frame.utils.BeanConvertUtil;
import com.fastCms.business.frame.utils.CommonsUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author lsquan
 * @since 2019-03-07
 */

@Transactional(rollbackFor = Exception.class)
@Component
@Slf4j
public class CloudMenuManageServiceImpl implements CloudMenuManageService {

    @Autowired
    private CloudMenuMapper cloudMenuMapper;

    @Autowired
    private CloudMenuService cloudMenuServiceImpl;

    @Autowired
    private CloudRoleMenuService cloudRoleMenuServiceImpl;

    @Autowired
    private CloudUserService cloudUserServiceImpl;

    @Autowired
    private CloudUserRoleRelService cloudUserRoleRelServiceImpl;

    @Override
    public ApiResponse<List<CloudMenuVO>> findMenuByUser(MenuOfUserPO param) {
        String userId = CloudUserManage.getUserId();
        String functionType = param.getFunctionType();

        CloudUser cloudUser = cloudUserServiceImpl.findById(userId);
        if (cloudUser == null) {
            return ResponseUtil.fail(ResultCodeConst.DATA_ERROR, ResultCodeConst.DATA_ERROR_MSG);
        }
        Integer adminType = cloudUser.getAdminType();
        String organizeCode = cloudUser.getOrganizeCode();
        //1.如果为超管,查超管自己的菜单,跟角色无关
        if (adminType == CloudAdminTypeEnum.SUPER_ADMIN.getCode()) {
            List<CloudMenuVO> superAdminMenu = findSuperAdminMenu(organizeCode);
            return ResponseUtil.success(superAdminMenu);

            //2.如果为管理员，直接查租户下的所有菜单
        } else if (adminType == CloudAdminTypeEnum.SYSTEM_ADMIN.getCode()) {
            List<CloudMenuVO> systemAdminMenu = findSystemAdminMenu(organizeCode, functionType);
            return ResponseUtil.success(systemAdminMenu);

            //3.如果为系统用户
        } else if (adminType == CloudAdminTypeEnum.SYSTEM_USER.getCode()) {
            CloudUserRoleRel roleRel = cloudUserRoleRelServiceImpl.findByUserId(userId);
            if (roleRel == null) {
                return ResponseUtil.fail(ResultCodeConst.DATA_ERROR, ResultCodeConst.DATA_ERROR_MSG);
            }
            List<CloudMenuVO> systemUserMenu = findSystemUserMenu(roleRel.getRoleId(), functionType);
            return ResponseUtil.success(systemUserMenu);
        }
        return ResponseUtil.fail(ResultCodeConst.DATA_ERROR, ResultCodeConst.DATA_ERROR_MSG);
    }

    @Override
    public List<CloudMenuVO> findByRoleId(String roleId) {
        //查出该出菜单，然后组合
        List<CloudMenu> cloudMenus = cloudMenuMapper.findByRoleId(roleId, null);
        return getMenuTree(cloudMenus);
    }

    @Override
    public ApiResponse<List<CloudMenuVO>> findMenuPoint(MenuPointOfUserPO param) {
        //用户的角色
        String menuId = param.getMenuId();
        String userId = CloudUserManage.getUserId();
        List<CloudMenu> resultEntities = cloudMenuMapper.findMenuPointByUser(userId, menuId);
        List<CloudMenuVO> cloudMenuVOS = BeanConvertUtil.convertList(resultEntities, CloudMenuVO.class);
        //角色下的菜单
        return ResponseUtil.success(cloudMenuVOS);
    }

    @Override
    public List<CloudMenuVO> findSuperAdminMenu(String organizeCode) {
        //查出该出菜单，然后组合
        List<CloudMenu> cloudMenus = cloudMenuServiceImpl.findByOrganizeCode(organizeCode, null);
        return getMenuTree(cloudMenus);
    }

    @Override
    public List<CloudMenuVO> findSystemAdminMenu(String organizeCode, String functionType) {
        //查出该出菜单，然后组合
        List<CloudMenu> cloudMenus = cloudMenuServiceImpl.findByOrganizeCode(organizeCode, functionType);
        return getMenuTree(cloudMenus);
    }

    @Override
    public List<CloudMenuVO> findSystemUserMenu(String roleId, String functionType) {
        //查出该出菜单，然后组合
        List<CloudMenu> cloudMenus = cloudMenuMapper.findByRoleId(roleId, functionType);
        return getMenuTree(cloudMenus);
    }

    @Override
    public boolean chooseMenu(String roleId, List<String> menuIds) {
        List<CloudRoleMenu> roleMenus = cloudRoleMenuServiceImpl.findByRoleId(roleId);

        //1.无需进行操作
        if (CollectionUtils.isEmpty(menuIds) && CollectionUtils.isEmpty(roleMenus)) {
            return true;
        }

        //2.初创，直接批量新增
        if (CollectionUtils.isNotEmpty(menuIds) && CollectionUtils.isEmpty(roleMenus)) {
            saveRoleMenuBatch(menuIds, roleId);
        }
        //3. 修改，先批量删除, 后批量新增
        if (CollectionUtils.isNotEmpty(menuIds) && CollectionUtils.isNotEmpty(roleMenus)) {
            List<CloudRoleMenu> cloudRoleMenus = roleMenus.stream().map(roleMenu -> {
                roleMenu.setState(CommonConst.STATE.INVALID);
                return roleMenu;
            }).collect(Collectors.toList());
            cloudRoleMenuServiceImpl.saveOrUpdateBatch(cloudRoleMenus);

            //批量新增
            saveRoleMenuBatch(menuIds, roleId);
        }
        return true;
    }

    /**
     * @Description 批量保存菜单
     * @Param [menuIds, date]
     * @Return void
     * @Date 2019/3/12 上午10:25 lsquan
     */
    public void saveRoleMenuBatch(List<String> menuIds, String roleId) {
        List<CloudRoleMenu> newCloudMenus = menuIds.stream().map(roleMenu -> {
            CloudRoleMenu cloudRoleMenu = new CloudRoleMenu();
            CommonsUtil.initEntity(cloudRoleMenu);
            cloudRoleMenu.setMenuId(roleMenu);
            cloudRoleMenu.setRoleId(roleId);
            return cloudRoleMenu;
        }).collect(Collectors.toList());
        cloudRoleMenuServiceImpl.saveBatch(newCloudMenus);
    }

    /**
     * @Description 获取菜单树状结构
     * @Param [cloudMenus]
     * @Date 2019/3/11 下午2:28 lsquan
     */
    public List<CloudMenuVO> getMenuTree(List<CloudMenu> cloudMenus) {

        //源数据转换VO
        List<CloudMenuVO> cloudMenuVOS = cloudMenus.stream().map(menu -> {
            CloudMenuVO cloudMenuVO = new CloudMenuVO();
            BeanUtils.copyProperties(menu, cloudMenuVO);
            return cloudMenuVO;
        }).collect(Collectors.toList());

        //list->map
        Map<String, CloudMenuVO> cloudMenuMap = cloudMenuVOS.stream().
                collect(Collectors.toMap(CloudMenuVO::getId, cloudMenuVO -> cloudMenuVO));

        //菜单数据组装
        List<CloudMenuVO> nodeTrees = new ArrayList<>();
        for (String id : cloudMenuMap.keySet()) {
            CloudMenuVO cloudMenu = cloudMenuMap.get(id);
            String parentId = cloudMenu.getPid();
            if (StringUtils.isBlank(parentId) || !cloudMenuMap.containsKey(parentId)) {
                nodeTrees.add(cloudMenu);
            } else {
                CloudMenuVO parentTreeNode = cloudMenuMap.get(parentId);
                if (CollectionUtils.isEmpty(parentTreeNode.getChildMenu())) {
                    parentTreeNode.setChildMenu(new ArrayList<>());
                }
                parentTreeNode.getChildMenu().add(cloudMenu);
                if (cloudMenu.getSort() != null) {
                    parentTreeNode.getChildMenu().sort(Comparator.comparing(CloudMenuVO::getSort)); //默认正序
                }

            }
        }
        //取根节点的树
        nodeTrees = nodeTrees.stream().filter(sysMenu -> StringUtils.isBlank(sysMenu.getPid())).
                collect(Collectors.toList());
        return nodeTrees;
    }
}
